
"""
Common funcions for both master and node.
"""

import logging
import logging.handlers
import os
import sys
import threading
import yaml


_DEFAULT_LOGGING_LEVEL = 'warning'


class scheduler(object):
    """Schedules a function to execute in `dt` milliseconds. If repeat is True, execution
    is repeated with `dt` downtime.
    Returns a scheduler object with a 'thread' attribute.
    Raises ValueError if dt is not positive."""
    def __init__(self, func, dt, repeat=False):
        if dt <= 0:
            raise ValueError('dt must be positive')

        def f():
            func()
            if repeat:
                scheduler(func, dt, repeat=True)

        self.thread = threading.Timer(dt/1000.0, f)
        self.thread.start()


def read_config(fname, opener=open):
    """Gets a yaml config file from the config directory.

    The configuration directory is ~/.gaweb/.

    Params:
      fname: The file name for the particular file to get
    """
    fname = '%s/.gaweb/%s' % (os.environ['HOME'], fname)

    self = read_config
    if not hasattr(self, 'last'):
        self._last = {}
    
    try:
        config = yaml.load(opener(fname))
        self._last[fname] = config
        return config
    except yaml.parser.ParserError, e:
        logging.error(e)
        if fname in self._last:
            return self._last[fname]
        else:
            raise e
    except IOError, e:
        logging.error(e)
        if fname in self._last:
            return self._last[fname]
        else:
            raise e


def setup_logging(user_config):
    """Setup the root logger.
    ``user_config'' is a dictionary from master.yaml or node.yaml.
    """
    level = {'debug': logging.DEBUG,
             'info': logging.INFO,
             'warning': logging.WARNING,
             'error': logging.ERROR,
             'critical': logging.CRITICAL
             }.get(user_config.get('logging', _DEFAULT_LOGGING_LEVEL).lower())
    
    filename = os.path.join(os.environ['HOME'], '.gaweb', '%s.log' % os.path.basename(sys.argv[0]))
    logging.basicConfig(level=level,
                        filename=filename,
                        format='%(asctime)s [ %(levelname)s ] %(message)s')
